#include "log.h"
#include <ctime>
#include <iomanip>

/*
 * Получаем дату в формате [%Y/%m/%d %H:%M:%S]
 */
std::string log_out::get_date() const {
  std::time_t now = std::time(nullptr);
  std::tm *local_time = std::localtime(&now);
  std::ostringstream oss; // Отдельный поток для даты

  //`local_time->tm_year` представляет текущий год, выраженный в количестве лет,
  // прошедших с 1900 года. Поэтому мы добавляем 1900, чтобы получить
  // фактический год.
  oss << "[" << 1900 + local_time->tm_year << "/"
      << 1 + local_time
                 ->tm_mon //`tm_mon` представляет месяц от 0 до 11, поэтому мы
                          // добавляем 1 для получения реального месяца.
      << "/" << local_time->tm_mday << " " << std::setfill('0')
      << std::setw(2) //
      << local_time->tm_hour << ":" << std::setfill('0')
      << std::setw(
             2) // Мы используем `std::setfill('0')` и `std::setw(2)` для того,
                // чтобы заполнить нулями (если необходимо) и выровнять вывод по
                // ширине 2 символа. Затем мы добавляем час.
      << local_time->tm_min << ":" << std::setfill('0')
      << std::setw(2)                // Минуты
      << local_time->tm_sec << "] "; // секунды

  return oss.str();
}

void log_out::write_log(text_info text_info, const std::string &text) {
  std::string date = get_date();
  switch (text_info) {
  case no_ok:
    sync_out.println(date, "\033[31m[-]\033[0m ", text);
    break;
  case ok:
    sync_out.println(date, "\033[32m[+]\033[0m ", text);
    break;
  case none_info:
    sync_out.println(date, text);
    break;
  case warring:
    sync_out.println(date, "\033[33m[*]\033[0m ", text);
    break;
  default:
    sync_out.println(date, "[?] ", text);
    break;
  }

  if (file_write) {
    std::ostringstream oss; // Отдельный поток для файла

    switch (text_info) {
    case no_ok:
      oss << date << "[-] " << text << std::endl;
      break;
    case ok:
      oss << date << "[+] " << text << std::endl;
      break;
    case none_info:
      oss << date << text << std::endl;
      break;
    case warring:
      oss << date << "[*] " << text << std::endl;
      break;
    default:
      oss << date << "[?] " << text << std::endl;
      break;
    }
    file_out_text << oss.str(); // Записываем строку в файл
  }
}

log_out::log_out() : file_write(false) {}

log_out::log_out(const std::string &filename) : file_write(true) {
  file_out_text.open(filename, std::ios::out | std::ios::app);
  // std::ios::out указывает на режим открытия файла для записи.
  // std::ios::app указывает на режим добавления в конец файла.
  if (file_out_text.is_open()) {
    write_log(log_out::ok, "Файл для логов успешно создан!");
  } else {
    file_write = false;
    write_log(log_out::no_ok, "Ошибка при создании файла для логов!");
  }
}

log_out::~log_out() {
  if (file_out_text.is_open() && file_write) {
    file_out_text.close();
  }
}
